/// \brief
///   State group that controls the rasterization properties
///
/// Note that not all states which are part of this state group are actually supported by all platforms. Please
/// refer to each platform's graphics documentation for information on which render states the hardware and graphics API
/// of that platform support.
class AEStateGroupRasterizerBase
{
public:
  AEUINT8 m_cFillMode;            ///< Fill mode. One of the members of the VFillMode enumeration.
  AEUINT8 m_cCullMode;            ///< Cull mode. One of the members of the VCullMode enumeration.
  AEFLOAT32 m_fDepthBias;                   ///< Depth Bias
  AEFLOAT32 m_fDepthBiasClamp;              ///< Depth Bias Clamp
  AEFLOAT32 m_fSlopeScaledDepthBias;        ///< Slope-scaled Depth Bias
  AEUINT8 m_cFlags;               ///< Bits: 1=FrontCounterClockwise, 2=DepthClipDisable, 4=ScissorEnable, 8=MultisamplingEnable
  AEUINT32 m_nHash;

private:
  AE_FORCEINLINE AEUINT32 ComputeHashInternal( void ) const
  {
    return ::ComputeHash( this, offsetof( AEStateGroupRasterizerBase, m_nHash ) );
  }


  public:

  /// \brief
  ///   Constructor; Sets defaults
  AE_FORCEINLINE AEStateGroupRasterizerBase( void ) 
  {
    memset( this, 0, sizeof( AEStateGroupRasterizerBase ) ); ///< turn off everything by default
    m_cFillMode = AEFILLMODE_SOLID;
    m_cCullMode = AECULLMODE_BACK;
    m_cFlags = AESHADER_RASTERIZERSTATEBIT_MULTISAMPLE;
  }

  /// \brief
  ///   Assignment operator
  AE_FORCEINLINE AEStateGroupRasterizerBase &operator = ( const AEStateGroupRasterizerBase &refOther )
  {
    memcpy( this, &refOther, sizeof( AEStateGroupRasterizerBase ) );
    return *this;
  }

  /// \brief
  ///   Comparison operator
  AE_FORCEINLINE AEBOOL32 operator == ( const AEStateGroupRasterizerBase &refOther ) const
  {
    if( m_nHash != refOther.m_nHash )
      return false;
    else
      return memcmp( this, &refOther, sizeof( AEStateGroupRasterizerBase ) ) == 0;
  }

  /// \brief
  ///   Comparison operator
  AE_FORCEINLINE AEBOOL32 operator != ( const AEStateGroupRasterizerBase &refOther ) const
  {
    return !( *this == refOther );
  }  

  /// \brief
  ///   Cleans up internally allocated data. 
  AE_FORCEINLINE void Cleanup( void )
  {
  }

  /// \brief
  ///   Computes the hash value for this state group. This function has to be called prior to using the state group.
  ///
  /// This function always has to be called after setting up a new state group or after modifying an existing state group.
  /// It computes a hash which is internally used for optimization purposes, and additionally generates platforms-specific
  /// data which is critical to the use of the state group.
  AE_FORCEINLINE void ComputeHash( void )
  {
    m_nHash = ComputeHashInternal();
  }

  /// \brief
  ///   Invalidates all states (for internal use)
  AE_FORCEINLINE void Invalidate( void )
  {
    ::InvalidateStates( this, sizeof( AEStateGroupRasterizerBase ) );
  }

  AE_FORCEINLINE AEBOOL32 IsHashValid( void ) const
  {
    return m_nHash == ComputeHashInternal();
  }
};